##################################################################################
# This script is to parse the following verbosegc 
##################################################################################
# Initializing
##################################################################################
BEGIN {
  gcNum = 0;

  maxRoots=0;
  minRoots=0;
  totalRoots=0;

  maxDepth=0;
  maxDepthGC=0;
  minDepth=0;
  totalDepth=0;
  maxLive=0;
  minLive=0;
  totalLive=0;
  maxLiveMS=0;
  minLiveMS=0;
  totalLiveMS=0;
  maxLDratio=0;
  minLDratio=0;
  totalLDratio=0;
  maxUsed = 0;
  maxUsedMS = 0;
  minUsed = 0;
  minUsedMS = 0;

  printDepth=0;
  printCycle=1;
  printTotal=0;
  consider=1;

  low=ARGV[2];
  if(low == 0) {
    low = 0;
  } 
  high=ARGV[3];
  if(high == 0) {
    high = 10;
  } 

  for(i=low; i <= high; i++ ) {
    procs=2^i;
    sumTime[procs]=0;
    maxTime[procs]=0;
    minTime[procs]=0;
    sumUtil[procs]=0;
    minUtil[procs]=0;
    maxUtil[procs]=0;
    sumSpeedup[procs]=0;
    minSpeedup[procs]=0;
    maxSpeedup[procs]=0;
    sumStalls[procs]=0;
    maxStalls[procs]=0;
    minStalls[procs]=0;
    sumStallP[procs]=0;
    maxStallP[procs]=0;
    minStallP[procs]=0;

    sumTime1[procs]=0;
    maxTime1[procs]=0;
    minTime1[procs]=0;
    sumUtil1[procs]=0;
    minUtil1[procs]=0;
    maxUtil1[procs]=0;
    sumSpeedup1[procs]=0;
    minSpeedup1[procs]=0;
    maxSpeedup1[procs]=0;
    sumStalls1[procs]=0;
    maxStalls1[procs]=0;
    minStalls1[procs]=0;
    sumStallP1[procs]=0;
    maxStallP1[procs]=0;
    minStallP1[procs]=0;

  }
   
  #printf("low=%d high=%d\n", low, high);
}

########################################################################
#===== DaCapo fop starting =====
########################################################################
/starting =====/{
  split( $0, a, " ");
  name=a[2];
  consider=1;
}

#######################################################
#===== DaCapo fop PASSED in 150357 msec =====
#######################################################
/PASSED/{
  consider=0;
}

#######################################################
# Ending with
# [End 305103.12 ms]
#######################################################
/End / {
  split( $0, a, " ");
  runTime=a[2];
  if(gcNum > 0 && printTotal  != 0) {
printf("name #GC maxR minR avgR  maxD  minD  avdD   maxL   minL   avgL  mxLms  mnLms  avLms  mxLDR  mnLDR  avLDR time maxDc mxU mxUms mnU mnUms \n");
    printf(name);
    printf(" %4d ", gcNum);

    printf("%4d ", maxRoots);
    printf("%4d ", minRoots); 
    printf("%4d ", totalRoots/gcNum);

    printf("%5d ", maxDepth);
    printf("%5d ", minDepth); 
    printf("%5d ", totalDepth/gcNum);

    printf("%6d ", maxLive);
    printf("%6d ", minLive); 
    printf("%6d ", totalLive/gcNum);

    printf("%6d ", maxLiveMS);
    printf("%6d ", minLiveMS); 
    printf("%6d ", totalLiveMS/gcNum);

    printf("%6d ", maxLDratio);
    printf("%6d ", minLDratio); 
    printf("%6d ", totalLDratio/gcNum);

    printf("%d ", runTime);
    printf("%d ", maxDepthGC);

    printf("%d ", maxUsed);
    printf("%d ", maxUsedMS);
    printf("%d ", minUsed);
    printf("%d \n", minUsedMS); 			

    printf("#cpu   minT    maxT     avgT   minSt   maxSt     avgSt   minU   maxU   avgU  minSp  maxSp  avgSp minStP maxStP avgStP\n");
    for(i=low; i <= high; i++ ) {
      procs=2^i;
      printf("%4d %6d %7d %8.1f %7d %7d %9.1f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", 
	     procs,
           minTime[procs], maxTime[procs], sumTime[procs]/gcNum,
           minStalls[procs], maxStalls[procs], sumStalls[procs]/gcNum,
           minUtil[procs], maxUtil[procs], sumUtil[procs]/gcNum,
	   minSpeedup[procs], maxSpeedup[procs], sumSpeedup[procs]/gcNum,
           minStallP[procs], maxStallP[procs], sumStallP[procs]/gcNum);

    }

    printf("#cpu   minT    maxT     avgT   minSt   maxSt     avgSt   minU   maxU   avgU  minSp  maxSp  avgSp minStP maxStP avgStP\n");
    for(i=low; i <= high; i++ ) {
      procs=2^i;
      printf("%4d %6d %7d %8.1f %7d %7d %9.1f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", 
	   procs,
           minTime1[procs], maxTime1[procs], sumTime1[procs]/gcNum,
           minStalls1[procs], maxStalls1[procs], sumStalls1[procs]/gcNum,
           minUtil1[procs], maxUtil1[procs], sumUtil1[procs]/gcNum,
	   minSpeedup1[procs], maxSpeedup1[procs], sumSpeedup1[procs]/gcNum,
           minStallP1[procs], maxStallP1[procs], sumStallP1[procs]/gcNum);
    }
  }
}

################################################################################
# cycle starts with
# Kathy Roots 128
################################################################################
/^Kathy Roots/ {
if(consider==1) {
  gcNum++;	
     
  gcDepth=0;
  gcPushed=0;
  gcPushedMS=0;
  gcMaxPushed=0;
  gcMaxPushedMS=0;
  gcMinPushed=0;
  gcMinPushedMS=0;
  gcTraced=0;
  gcTracedMS=0;

  split( $0, a, " ");
  roots=a[3];
  totalRoots += roots;
  if(roots > maxRoots) {
    maxRoots = roots;
  }
  if(roots < minRoots || minRoots == 0) {
    minRoots = roots;
  }

  for(i=low; i <= high; i++ ) {
    procs=2^i;
    acessesD[procs]=0;
    stallsD[procs]=0;
    workLeftD[procs]=0;

    lookForO[procs]=0;
    acessesO[procs]=0;
    stallsO[procs]=0;
  }
 }
}

################################################################################
# for each popped object the report is
# Kathy object 1 5
################################################################################
/^Kathy Object/ {
if(consider==1 ) {
     split( $0, a, " ");

     popped=a[3];
     pushed=a[4];

     work=pushed-popped;
     
     for(i=low; i <= high; i++ ) {
       procs=2^i;

       if(popped == lookForO[procs]) {
	 if(work > procs) {
	   remain=work%procs;
	   acessesO[procs] += work - remain;
	 } else {
	   remain = 0;
	   acessesO[procs] += procs;
	   stallsO[procs] += procs-work;
	 }
	 lookForO[procs] = pushed-remain;

	 printf("%2d %4d %7d %7d %5d %5d %7d %5d %7d\n", i, procs, popped, pushed, work, remain, acessesO[procs], stallsO[procs], lookForO[procs]);
       }
     }
 }
}

################################################################################
# at each depth the report is
# Kathy Depth 1 PusV: 25456 lo: 1 nm: 895 sce: 400 lc: 0 imm: 8 md: 0 vm: 0 myms: 24152 Trace 39871 ms: 24291
################################################################################
/^Kathy Depth/ {
if(consider==1 ) {
     split( $0, a, " ");
     gcDepth=a[3];
     pushed=a[5];
     pushedMS=a[21];
     traced=a[23];
     tracedMS=a[25];

     gcPushed += pushed;
     if(gcPushed > gcMaxPushed) {
       gcMaxPushed = gcPushed;
     }
     if(gcPushed < gcMinPushed || gcMinPushed == 0) {
       gcMinPushed = gcPushed;
     }

     gcPushedMS += pushedMS;
     if(gcPushedMS > gcMaxPushedMS) {
       gcMaxPushedMS = gcPushedMS;
     }
      if(gcPushedMS < gcMinPushedMS || gcMinPushedMS == 0) {
       gcMinPushedMS = gcPushedMS;
     }

     gcTraced += traced;;
     gcTracedMS += tracedMS;
     
     if(printDepth == 1) {
       printf("%d %d %d %d %d %d\n", gcNum, gcDepth, pushed, pushedMS, traced, tracedMS);
     }

     for(i=low; i <= high; i++ ) {
       procs=2^i;
       newWork=pushed;
       oldWork=workLeftD[procs];
       if(oldWork > procs) {
	  printf("Error: oldWork=%d, procs=%d\n", oldwork, procs);				
       }
       thisWork=newWork+oldWork;    
       if(thisWork < procs) {
          #count stalls
          workLeft = 0;
          acesses = procs;
	  stalls=procs-thisWork;
       } else {
          #no stalls
workLeft = thisWork%procs;
acesses = thisWork-workLeft;
          stalls=0;
       }
       #printf("%2d %4d %5d %5d %5d %5d %5d %5d\n", i, procs, newWork, oldWork, thisWork, acesses, workLeft, stalls);
       acessesD[procs] += acesses;
       stallsD[procs] += stalls;
       workLeftD[procs] = workLeft;
     }
 }
}

################################################################################
# cycle ends with
# Kathy Cycle 333 Depth 16 Pushed 241255 ms 237863 min 1 max 51724 avg 15078
################################################################################
/^Kathy Cycle / {
if(consider==1) {
  split( $0, a, " ");
  
  if(gcDepth > maxDepth) {
    maxDepth = gcDepth;
    maxDepthGC = gcNum;
  }
  if(gcDepth < minDepth || minDepth == 0) {
    minDepth = gcDepth;
  }
  totalDepth += gcDepth;

  if(gcPushed > maxLive) {
    maxLive = gcPushed;
  }
  if(gcPushed < minLive || minLive == 0) {
    minLive = gcPushed;
  }
  totalLive += gcPushed;

  if(gcPushedMS > maxLiveMS) {
    maxLiveMS = gcPushedMS;
  }
  if(gcPushedMS < minLiveMS || minLiveMS == 0) {
    minLiveMS = gcPushedMS;
  }
  totalLiveMS += gcPushedMS;

  ldRatio = gcPushed/gcDepth;
  if(ldRatio > maxLDratio) {
    maxLDratio = ldRatio;
  }
  if(ldRatio < minLDratio || minLDratio == 0) {
    minLDratio = ldRatio;
  }
  totalLDratio += ldRatio;
 
  if(printCycle==1 ) {
    printf("GC %d: Depth=%d Pushed=%d\n", gcNum, gcDepth, gcPushed);
  }
  
  for(i=low; i <= high; i++ ) {
      procs=2^i;


      if(workLeftD[procs] > 0 ) {
        acessesD[procs] += procs;
	stallsD[procs] += procs-workLeftD[procs];
      }
      utilD[procs]=(gcPushed*100.0)/acessesD[procs];
      speedupD[procs]=(gcPushed*procs)/acessesD[procs];
      stallpD[procs]=(stallsD[procs]*100.0)/acessesD[procs];

      if(printCycle==1 ) {
        printf("i=%d procs=%d acessesD=%d stallsD=%d utilD=%.2f speedupD=%.2f stallpD=%.2f\n", i, procs, acessesD[procs], stallsD[procs], utilD[procs], speedupD[procs], stallpD[procs]);
      }

      #new computations
      #TODO - account for the remaining work
      
      utilO[procs]=(gcPushed*100.0)/acessesO[procs];
      speedupO[procs]=(gcPushed*procs)/acessesO[procs];
      stallpO[procs]=(stallsO[procs]*100.0)/acessesO[procs];

      if(printCycle==1 ) {
        printf("i=%d procs=%d acessesO=%d stallsO=%d utilO=%.2f speedupO=%.2f stallpO=%.2f\n", i, procs, acessesO[procs], stallsO[procs], utilO[procs], speedupO[procs], stallpO[procs]);
      }
  }	
}
}
#############################################################
# After Collection: used = 5.78 Mb = boot 0.00 Mb + immortal 0.12 Mb + meta 0.00 Mb + los 0.70 Mb + sanity 0.00 Mb + non-movi
# ng 0.14 Mb + sm-code 0.17 Mb + lg-code 0.00 Mb + myms 4.62 Mb
#############################################################
/After Collection: / {
if(consider==1) {
  split( $0, a, " ");
  used=a[5];
  if(used > maxUsed) {
    maxUsed = used;
  }
  if(used < minUsed || minUsed == 0) {
    minUsed = used;
  }

  usedMS=a[41];
  if(usedMS > maxUsedMS) {
    maxUsedMS = usedMS;
  }
  if(usedMS < minUsedMS || minUsedMS == 0) {
    minUsedMS = usedMS;
  }
}
}




